using BitBenderGames;
using DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using Yoozoo.Mars.Got.Timer;

namespace Yoozoo.Gameplay.City
{
    [Serializable] 
    public class AreaWallData
    {
        [Header("解开区域ID")]
        public int areaId;
        
        [Header("需要显示的围墙")]
        public List<GameObject> showWalls;
        [Header("锁定时显示的地表")]
        public GameObject lockGround;
        [Header("解锁时显示的地表")]
        public GameObject unlockGround;
        [Header("解锁时的特效")]
        public GameObject unlockGroundEffect;
        [Header("解锁时摄像机观察点")]
        public GameObject lookAtPoint;
        [Header("解锁时摄像机距离，-1:保持不变")]
        [Range(-1, 999)]
        public int zoomDistance = -1;

        [Header("解锁迷雾时的动画")] 
        public GameObject unlockFogAni;
        [Header("区域解锁前水池")] 
        public GameObject unlockWater;

        [Header("区域可占领特效")]
        public GameObject containerEffect;
        
        public void HideWall()
        {
            if (showWalls!=null)
            {
                foreach (var wall in showWalls)
                {
                    if (wall && wall.activeSelf)
                    {
                        wall.SetActive(false);
                    }
                }
            }
        }

        public void ShowWall()
        {
            if (showWalls!=null)
            {
                foreach (var wall in showWalls)
                {
                    if (wall && !wall.activeSelf)
                    {
                        wall.SetActive(true);
                    }
                }
            }
        }

        public void UnlockGround()
        {
            if (lockGround) 
                lockGround.SetActive(false);
            if (containerEffect)
            {
                containerEffect.SetActive(false);
            }
            if (unlockGround) 
                unlockGround.SetActive(true);
            if (unlockGroundEffect)
                unlockGroundEffect.SetActive(false);
            if (containerEffect)
                containerEffect.SetActive(false);
        }

        public void PlayContainerEffect()
        {
            if (containerEffect)
                containerEffect.SetActive(true);
        }

        public void HideContainerEffect()
        {
            if (containerEffect)
                containerEffect.SetActive(false);
        }

        public void PlayUnlockGoundEffect(float loakAtDelayTime, Action completeCallback)
        {
            Timing.Instance.CallDelayedOnInstance(loakAtDelayTime, () =>
            {
                if (containerEffect)
                {
                    containerEffect.SetActive(false);
                }
                if (unlockGroundEffect)
                {
                    if (unlockGround)
                    {
                        unlockGroundEffect.transform.parent = unlockGround.transform.parent;
                    }
                    unlockGroundEffect.SetActive(true);
                }
                if (lockGround)
                {
                    var animation = lockGround.GetComponentInChildren<Animation>();
                    if (animation)
                    {
                        animation.Play();
                    }
                    else
                    {
                        lockGround.SetActive(false);
                        if (unlockGround)
                        {
                            unlockGround.SetActive(true);
                        }
                    }
                    
                    if (containerEffect && containerEffect.activeSelf)
                    {
                        containerEffect.SetActive(false);
                    }
                    
                    Timing.Instance.CallDelayedOnInstance(2f, () =>
                    {
                        if (unlockGroundEffect)
                        {
                            unlockGroundEffect.SetActive(false);
                        }

                        if (containerEffect && containerEffect.activeSelf)
                        {
                            containerEffect.SetActive(false);
                        }
                        
                        completeCallback?.Invoke();
                    });
                }
            });
        }

        public void LockGround()
        {
            if (lockGround) 
                lockGround.SetActive(true);
            if (containerEffect)
            {
                containerEffect.SetActive(true);
            }
            if (unlockGround) 
                unlockGround.SetActive(false);
            if (unlockGroundEffect)
                unlockGroundEffect.SetActive(false);
            if (containerEffect)
                containerEffect.SetActive(false);
        }

        public void UnlockAreaFogAni(Action callBack)
        {
            if (unlockFogAni)
            {
                unlockFogAni.SetActive(true);
                Timing.Instance.CallDelayedOnInstance(2, () =>
                {
                    unlockFogAni.SetActive(false);
                    callBack?.Invoke();
                });
            }
            else
            {
                Timing.Instance.CallDelayedOnInstance(2, () =>
                {
                    callBack?.Invoke();
                });
            }
        }

        public void HideUnlockWater()
        {
            if (lockGround)
            {
                var water = lockGround.transform.Find("LOD0/mesh_innercity_river_old");
                if (water)
                {
                    water.gameObject.SetActive(false);
                }
            }
            
        }

        public void ShowBusinessEffect(bool needShowAni, Action callBack = null)
        {
            if (unlockGround)
            {
                //先播放地板动画，再播放地毯动画
                Animator floorAni = unlockGround.transform.GetChild(0).GetComponent<Animator>();
                MeshRenderer floorMesh = unlockGround.transform.GetChild(0).GetComponent<MeshRenderer>();
                Animator carpetAni = unlockGround.transform.GetChild(1).GetComponent<Animator>();
                MeshRenderer carpetMesh = unlockGround.transform.GetChild(1).GetComponent<MeshRenderer>();
                var decorate = unlockGround.transform.GetChild(2);
                unlockGround.gameObject.SetActive(true);
                if (needShowAni)
                {
                    floorMesh.enabled = false;
                    carpetMesh.enabled = false;
                    decorate.gameObject.SetActive(true);
                    floorAni.gameObject.SetActive(true);
                    floorAni.enabled = true;
                    carpetAni.gameObject.SetActive(true);
                    carpetAni.enabled = true;
                    
                    floorMesh.enabled = true;
                        
                    floorAni.SetTrigger("Floor");
                    carpetMesh.enabled = true;
                    carpetAni.SetTrigger("roll");
                    Timing.Instance.CallDelayedOnInstance(1.5f, () =>
                    {
                        callBack?.Invoke();
                    });
                    
                }
                else
                {
                    floorAni.gameObject.SetActive(true);
                    carpetAni.gameObject.SetActive(true);
                    decorate.gameObject.SetActive(true);
                    floorAni.enabled = true;
                    carpetAni.enabled = true;
                    
                }
                
            }
        }

        public void HideBusinessEffect()
        {
            if (unlockGround)
            {
                Animator floorAni = unlockGround.transform.GetChild(0).GetComponent<Animator>();
                Animator carpetAni = unlockGround.transform.GetChild(1).GetComponent<Animator>();
                var decorate = unlockGround.transform.GetChild(2);
                floorAni.gameObject.SetActive(false);
                carpetAni.gameObject.SetActive(false);
                decorate.gameObject.SetActive(false);
            }
        }

        public void ShowOrHideAreaUnlockEffect(bool showState)
        {
            if (lockGround)
            {
                lockGround.gameObject.SetActive(true);
                var root = lockGround.transform.Find("LOD0/sfx_rpg_miwu");
                if (root)
                {
                    root.gameObject.SetActive(true);
                    var effect = root.Find("sfx_rpg_miwu_huang");
                    if (effect)
                    {
                        effect.gameObject.SetActive(showState);
                    }
                }
            }
        }

        public void ShowOrHideAreaMoneyEffect(bool showState)
        {
            if (lockGround)
            {
                lockGround.gameObject.SetActive(true);
                var root = lockGround.transform.Find("LOD0/sfx_rpg_miwu");
                if (root)
                {
                    root.gameObject.SetActive(true);
                    var effect = root.Find("sfx_rpg_miwu_lan");
                    if (effect)
                    {
                        effect.gameObject.SetActive(showState);
                    }
                }
            }
        }
    }
    
    //[ExecuteAlways]
    public class CityWallComponent : MonoBehaviour
    {
        public List<AreaWallData> areaWallDataList;

        private Dictionary<int, AreaWallData> _wallDataMap;

        [SerializeField]
        private AreaWallData _currentWallData;

        public CameraMoveComponent cameraMoveComponent;

        public string showWallAnimationName = "ani_sfx_InnerCity_61004_huanyuan_qiang";

        public string showColumnAnimationName = "ani_sfx_InnerCity_61004_huanyuan_zhuzi";
        
        public string showWindowAnimationName = "ani_sfx_InnerCity_61004_huanyuan_qiang_chuang";
        
        public string hideWallAnimationName = "ani_sfx_InnerCity_61004";

        public float loakAtDelayTime = 20f;

        private float cameraLookAtSpeedTime = 0.7f;

        public float unlockFogCameraTime = 0.6f;

        private void Awake()
        {
            _wallDataMap = new Dictionary<int, AreaWallData>();
            foreach (var wallData in areaWallDataList)
            {
                _wallDataMap[wallData.areaId] = wallData;
                wallData.HideWall();
            }

            _currentWallData = null;
        }
        
        private void OnDestroy()
        {
            cameraMoveComponent = null;
        }

        private void PlayHideWall(GameObject go)
        {
            var components = go.GetComponentsInChildren<Animation>();
            foreach (var component in components)
                component.Play(hideWallAnimationName);
        }

        private void PlayShowWall(GameObject go)
        {
            string wallName;
            var components = go.GetComponentsInChildren<Animation>();
            foreach (var component in components)
            {
                string animationName = GetWallAnimationName(component);
                if (!string.IsNullOrEmpty(animationName))
                {
                    component.Play(animationName);
                }
            }
        }

        public string GetWallAnimationName(Animation component)
        {
            string wallName = component.transform.parent.name;
            if (wallName.Contains("innercity_outwall_01")||wallName.Contains("innercity_outwall_03"))
            {
                return showWallAnimationName;
            }
            else if (wallName.Contains("innercity_outwall_04"))
            {
                return showWindowAnimationName;
            }
            else if (wallName.Contains("innercity_outwall_05")||wallName.Contains("innercity_outwall_06")||wallName.Contains("innercity_outwall_07"))
            {
                return showColumnAnimationName;
            }
            return string.Empty;
        }

        public void InitAreaWall(int areaId, int maxUnlockedAreaCount)
        {
            AreaWallData areaWallData;
            if (_wallDataMap.TryGetValue(areaId, out areaWallData))
            {
                areaWallData.HideWall();
                if (areaId == 1 && _currentWallData == null)
                {
                    _currentWallData = areaWallData;
                }
                if (areaId <= maxUnlockedAreaCount)
                {
                    areaWallData.UnlockGround();
                }
                else
                {
                    areaWallData.LockGround();
                }
                
                if (areaId == maxUnlockedAreaCount)
                {
                    areaWallData.ShowWall();
                    _currentWallData = areaWallData;
                }
            }
        }
        
        public void SetAreaWallData(int areaId, GameObject lockGround, GameObject unlockGround, GameObject unlockGroundEffect ,List<GameObject> showWalls, GameObject containerEffect)
        {
            AreaWallData areaWallData;
            if (_wallDataMap.TryGetValue(areaId, out areaWallData))
            {
                areaWallData.lockGround = lockGround;
                areaWallData.unlockGround = unlockGround;
                areaWallData.unlockGroundEffect = unlockGroundEffect;
                areaWallData.showWalls = showWalls;
                areaWallData.containerEffect = containerEffect;
            }
        }

        public void HideAllWalls()
        {
            foreach (var wallData in areaWallDataList)
            {
                wallData.HideWall();
            }
        }

        /// <summary>
        /// 再次刷新解锁区域，用于切换场景时动画被打断;地面不用，因为切回场景lockground根据解锁状态隐藏了
        /// </summary>
        /// <param name="areaId"></param>
        public void RefreshUnlockArea(int areaId)
        {
            // 隐藏上一个区域的围墙，显示下一个区域的围墙, 可能存在重复部分，先进行判断
            AreaWallData wallData;
            List<GameObject> lastAreaWalls = null;
            if (_wallDataMap.TryGetValue(areaId - 1, out wallData))
            {
                lastAreaWalls = wallData.showWalls;
            }
            List<GameObject> unlockAreaWalls = null;
            if (_wallDataMap.TryGetValue(areaId, out wallData))
            {
                unlockAreaWalls = wallData.showWalls;
            }

            // 隐藏上一个区域的墙，防止隐藏动画被打断
            if (lastAreaWalls != null)
            {
                foreach (var hideWall in lastAreaWalls)
                {
                    // 判断是否隐藏
                    if (!(unlockAreaWalls!=null && unlockAreaWalls.Contains(hideWall)))
                    {
                        hideWall.SetActive(false);   
                    }
                }
            }
            
            // 显示当前解锁区域的墙，并重置刚解锁的墙的动画状态
            if (unlockAreaWalls != null)
            {
                foreach (var showWall in unlockAreaWalls)
                {
                    showWall.SetActive(true);
                    // 重置这个区域刚解锁的墙上的动画状态到最后一帧，防止切换场景没有播完
                    if (!(lastAreaWalls!=null && lastAreaWalls.Contains(showWall)))
                    {
                        var components = showWall.GetComponentsInChildren<Animation>();
                        foreach (var component in components)
                        {
                            string animationName = GetWallAnimationName(component);
                            if (!string.IsNullOrEmpty(animationName))
                            {
                                ResetAnimationToEnd(component, animationName);
                                component.Play(animationName);
                            }
                        }
                    }
                }
            }
            
        }

        void ResetAnimationToEnd(Animation component, string animationName)
        {
            AnimationState state = component[animationName];
            component.Play(animationName);
            state.normalizedTime = 1;
            component.Sample();
            state.enabled = false;
        }

        // 显示可占领特效
        public void PlayContainerEffect(int areaId)
        {
            if (_wallDataMap.ContainsKey(areaId))
            {
                _wallDataMap[areaId].PlayContainerEffect();
            }
        }
        
        // 隐藏可占领特效
        public void HideContainerEffect(int areaId)
        {
            if (_wallDataMap.ContainsKey(areaId))
            {
                _wallDataMap[areaId].HideContainerEffect();
            }
        }

        public void UnlockArea(int areaId, bool isPlayEffect, Action completeCallback = null)
        {
            if (!Application.isPlaying)
            {
                _wallDataMap = new Dictionary<int, AreaWallData>();
                foreach (var wallData in areaWallDataList)
                {
                    _wallDataMap[wallData.areaId] = wallData;
                }
            }

            // // 摄像机移动到指定位置
            // if (isPlayEffect && cameraMoveComponent)
            // {
            //     var wallData = _wallDataMap[areaId];
            //     var lookAtPoint = wallData.lookAtPoint;
            //     if (lookAtPoint)
            //     {
            //         var position = lookAtPoint.transform.position;
            //         var vector = new Vector2(position.x, position.z);
            //         cameraMoveComponent.TweenFocusAtByTime(vector, loakAtDelayTime, Ease.Linear, wallData.zoomDistance);
            //     }
            // }
            
            // 隐藏可占领特效
            HideContainerEffect(areaId);

            // 隐藏上一个区域的围墙，显示下一个区域的围墙, 可能存在重复部分，先进行判断
            var currentAreaWalls = _currentWallData?.showWalls ?? new List<GameObject>();
            var unlockAreaWalls = _wallDataMap[areaId]?.showWalls ?? new List<GameObject>();
            var hideWalls = new List<GameObject>();
            var showWalls = new List<GameObject>();
            foreach (var wall in currentAreaWalls)
            {
                if (wall && !unlockAreaWalls.Contains(wall))
                    hideWalls.Add(wall);
            }

            foreach (var wall in unlockAreaWalls)
            {
                if (wall && !currentAreaWalls.Contains(wall))
                    showWalls.Add(wall);
            }
            // 隐藏墙体
            foreach (var wall in hideWalls)
            {
//                if (isPlayEffect)
//                    PlayHideWall(wall);
//                else
                wall.SetActive(false);
            }
            // for (int i = 1; i <= areaWallDataList.Count; i++)
            // {
            //     if (_wallDataMap.ContainsKey(i))
            //     {
            //         if (i <= areaId)
            //         {
            //             if (isPlayEffect && i == areaId)
            //             {
            //                 _wallDataMap[i].PlayUnlockGoundEffect(loakAtDelayTime);
            //             }
            //             else
            //             {
            //                 _wallDataMap[i].UnlockGround();
            //             }
            //         }
            //         else
            //         {
            //             _wallDataMap[i].LockGround();
            //         }
            //     }
            // }
            if (isPlayEffect)
            {
                _wallDataMap[areaId].PlayUnlockGoundEffect(0, completeCallback);
                //墙的动画延迟1s播放
                Timing.Instance.CallDelayedOnInstance(2, () => { UnlockWall(areaId, isPlayEffect, showWalls); });
            }
            else
            {
                _wallDataMap[areaId].UnlockGround();
                completeCallback?.Invoke();
                UnlockWall(areaId, isPlayEffect, showWalls);
            }
            _currentWallData = _wallDataMap[areaId];
        }

        public void InitAreaState(int areaId, bool isUnlock)
        {
            if (!Application.isPlaying)
            {
                _wallDataMap = new Dictionary<int, AreaWallData>();
                foreach (var wallData in areaWallDataList)
                {
                    _wallDataMap[wallData.areaId] = wallData;
                }
            }
            
            // 隐藏上一个区域的围墙，显示下一个区域的围墙, 可能存在重复部分，先进行判断
            var currentAreaWalls = _currentWallData?.showWalls ?? new List<GameObject>();
            var unlockAreaWalls = _wallDataMap[areaId]?.showWalls ?? new List<GameObject>();
            var hideWalls = new List<GameObject>();
            var showWalls = new List<GameObject>();
            foreach (var wall in currentAreaWalls)
            {
                if (wall && !unlockAreaWalls.Contains(wall))
                    hideWalls.Add(wall);
            }

            foreach (var wall in unlockAreaWalls)
            {
                if (wall && !currentAreaWalls.Contains(wall))
                    showWalls.Add(wall);
            }
            // 隐藏墙体
            foreach (var wall in hideWalls)
            {
//               
                wall.SetActive(false);
            }
          
            if (isUnlock)
            {
                _wallDataMap[areaId].UnlockGround();
            }
            else
            {
                _wallDataMap[areaId].LockGround();
            }
            _currentWallData = _wallDataMap[areaId];
            
            // Debug.LogError($"InitAreaState {areaId}: {isUnlock}");
            // Debug.LogError($"InitAreaState hideWalls: {hideWalls.Count}");
            // Debug.LogError($"InitAreaState showWalls: {showWalls.Count}");
            
            UnlockWall(areaId, false, showWalls);
        }

        public void UnlockWall(int areaId, bool isPlayEffect, List<GameObject>showWalls)
        {
            if (gameObject == null)
            {
                return;
            }
            // 显示墙体
            foreach (var wall in showWalls)
            {
                wall.SetActive(true);
                if (isPlayEffect)
                    PlayShowWall(wall);
            }

        }

        public void UnlockAreaFogAni(int areaId,Action callBack)
        {
            areaId += 1000;
            
            var wallData = GetWallDataFromMap(areaId);
            if (wallData != null)
            {
                // 摄像机移动到指定位置
                if (cameraMoveComponent)
                {
                    var lookAtPoint = wallData.lookAtPoint;
                    if (lookAtPoint)
                    {
                        var position = lookAtPoint.transform.position;
                        var vector = new Vector2(position.x, position.z);
                        cameraMoveComponent.TweenFocusAtByTime(vector, unlockFogCameraTime, Ease.Linear, wallData.zoomDistance,(
                            () =>
                            {
                                wallData.UnlockAreaFogAni(() =>
                                {
                                    callBack?.Invoke();
                                });
                            }));
                    }
                }
                
                
               
            }
        }

        public int GetAreaId(int index)
        {
            var areaWallData = areaWallDataList[index];
            return areaWallData.areaId;
        }

        public void HideUnlockWater(int areaId)
        {
            var wallData = GetWallDataFromMap(areaId);
            wallData?.HideUnlockWater();
        }

        public void CameraToLookAt(int areaId, Action cameraCallBack)
        {
            var wallData = GetWallDataFromMap(areaId);
            var lookAtPoint = wallData.lookAtPoint;
            if (lookAtPoint)
            {
                var position = lookAtPoint.transform.position;
                var vector = new Vector2(position.x, position.z);
                cameraMoveComponent.TweenFocusAtByTime(vector, cameraLookAtSpeedTime, Ease.Linear, wallData.zoomDistance,(
                    () =>
                    {
                        cameraCallBack?.Invoke();
                    }));
            }
        }
        public void ShowBusinessEffect(bool needShowAni, Action callBack)
        {
            var wallData = GetWallDataFromMap(1);
            if (wallData != null)
            {
                // 摄像机移动到指定位置
                if (needShowAni)
                {
                    wallData.ShowBusinessEffect(needShowAni, () =>
                    {
                        callBack?.Invoke();
                    });

                    return;
                }
                wallData.ShowBusinessEffect(needShowAni);
            }
        }
        public void HideBusinessEffect()
        {
            var wallData = GetWallDataFromMap(1);
            if (wallData != null)
            {
                wallData.HideBusinessEffect();
            }
        }

        public void ShowOrHideAreaUnlockEffect(int areaId, bool showState)
        {
            var wallData = GetWallDataFromMap(areaId);
            if (wallData != null)
            {
                wallData.ShowOrHideAreaUnlockEffect(showState);
            }
        }

        public void ShowOrHideAreaMoneyEffect(int areaId, bool showState)
        {
            var wallData = GetWallDataFromMap(areaId);
            if (wallData != null)
            {
                wallData.ShowOrHideAreaMoneyEffect(showState);
            }
        }


        private AreaWallData GetWallDataFromMap(int areaId)
        {
            if (_wallDataMap != null)
            {
                if (_wallDataMap.TryGetValue(areaId, out var data) && data != null)
                {
                    return data;
                }
            }
            return null;
        }
    }
}
